﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

using Obsidian.Config;
using Obsidian.Utils;

namespace Oak.Config
{
    public class SessionConfig
    {

        private static DateTime modified = DateTime.MinValue;
        private static SessionInfo sessionInfo;

        public static SessionInfo GetSessionInfo()
        {
            CheckForChanged();
            return sessionInfo;
        }

        private static void CheckForChanged()
        {
            if (AppConfig.CheckForChanged() || !AppConfig.Modified.Equals(modified))
            {
                GetConfigInfo();
                modified = AppConfig.Modified;
            }
        }

        private static void GetConfigInfo()
        {
            sessionInfo = new SessionConfig.SessionInfo();
            XmlDocument xmlDoc = AppConfig.GetXml();
            XmlNode node = xmlDoc.SelectSingleNode("appConfig/oak/session");
            if (node == null)
                return;
            string val;
            if (!XmlUtil.TryGetAttrValue(node, "db", out val))
                val = null;
            else
            {
                val = val.Trim();
                if (val.Length == 0)
                    throw new Exception("配置项appConfig/oak/session 属性db值不能为空");
            }
            sessionInfo.SetDbName(val);

            if (!XmlUtil.TryGetAttrValue(node, "memcached", out val))
                val = null;
            else
            {
                val = val.Trim();
                if (val.Length == 0)
                    throw new Exception("配置项appConfig/oak/session 属性memcached值不能为空");
            }
            sessionInfo.SetMemcachedClient(val);

            if ((String.IsNullOrEmpty(sessionInfo.DbName) && String.IsNullOrEmpty(sessionInfo.MemcachedClient)) ||
                (!String.IsNullOrEmpty(sessionInfo.DbName) && !String.IsNullOrEmpty(sessionInfo.MemcachedClient)))
            {
                throw new Exception("配置项appConfig/oak/session 属性db和memcached不能同时存在，也不能同时为空");
            }
            if(!String.IsNullOrEmpty(sessionInfo.DbName))
                sessionInfo.SetType(SessionType.DataBase);
            else if(!String.IsNullOrEmpty(sessionInfo.MemcachedClient))
                sessionInfo.SetType(SessionType.Memcached);
            
            int validTime;
            if (!XmlUtil.TryGetAttrInt(node, "validTime", out validTime))
                throw new Exception("配置项appConfig/oak/session 属性validTime错误");
            if(validTime <= 0)
                throw new Exception("配置项appConfig/oak/session 属性validTime错误，必须大于0");
            sessionInfo.SetValidTime(validTime);

        }

        public class SessionInfo
        {
            private SessionType type = SessionType.Unset;
            private string dbName = null;
            private string memcachedClient = null;
            private int validTime = 30;

            public SessionType Type
            {
                get { return type; }
            }

            public string DbName
            {
                get { return dbName; }
            }

            public string MemcachedClient
            {
                get { return memcachedClient; }
            }

            public int ValidTime
            {
                get { return validTime; }
            }

            public void SetType(SessionType type)
            {
                this.type = type;
            }

            public void SetDbName(string dbName)
            {
                this.dbName = dbName;
            }

            public void SetMemcachedClient(string client)
            {
                this.memcachedClient = client;
            }

            public void SetValidTime(int validTime)
            {
                this.validTime = validTime;
            }

        }

        public enum SessionType
        {
            Unset,
            DataBase,
            Memcached
        }

    }
}
